package lesson5.example7;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.tools.jcore.ClassFilter;
import sun.jvm.hotspot.tools.jcore.ClassWriter;

public class DumpWrapperFilter implements ClassFilter {

	@Override
	public boolean canInclude(InstanceKlass kls) {
		String klassName = kls.getName().asString().replace('/', '.');
		if (klassName.contains("String")) {
			dumpKlass(kls);
		}
		return false;
	}


	private void dumpKlass(InstanceKlass kls) {

		String klassName = kls.getName().asString();

		klassName = klassName.replace('/', File.separatorChar);

		File outDest = new File(
				"/media/mazhi/sourcecode/workspace/projectjava5/bytecode-examples/bytecode-example-5-04/lib");

		if (kls.getClassLoader() != null) {
			outDest.mkdirs();
			File classLoaderInfo = new File(outDest, "classLoader.txt");
			if (!classLoaderInfo.exists()) {
				FileOutputStream out = null;
				try {
					out = new FileOutputStream(classLoaderInfo);
					out.write(kls.getClassLoader().toString().getBytes("UTF-8"));
					out.flush();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					if (out != null) {
						try {
							out.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}

		}

		try {
			OutputStream os = null;
			int index = klassName.lastIndexOf(File.separatorChar);
			File dir = null;
			if (index != -1) {
				String dirName = klassName.substring(0, index);
				dir = new File(outDest, dirName);
			} else {
				dir = outDest;
			}
			dir.mkdirs();
			File f = new File(dir, klassName.substring(index + 1) + ".class");
			f.createNewFile();
			os = new BufferedOutputStream(new FileOutputStream(f));
			try {
				ClassWriter cw = new ClassWriter(kls, os);
				cw.write();
			} finally {
				if (os != null) {
					os.close();
				}
			}
		} catch (IOException exp) {
			exp.printStackTrace();
		}
	}
}
